import {getRandomData} from "@/utils/utils";

export function getParametricEquation(startRatio,endRatio,isSelected,isHovered,k,height){
    // 计算
    let midRatio = (startRatio + endRatio) / 2;

    let startRadian = startRatio * Math.PI * 2;
    let endRadian = endRatio * Math.PI * 2;
    let midRadian = midRatio * Math.PI * 2;

    // 如果只有一个扇形，则不实现选中效果。
    if (startRatio === 0 && endRatio === 1) {
        isSelected = false;
    }

    // 通过扇形内径/外径的值，换算出辅助参数 k（默认值 1/3）
    k = typeof k !== "undefined" ? k : 1 / 3;

    // 计算选中效果分别在 x 轴、y 轴方向上的位移（未选中，则位移均为 0）
    let offsetX = isSelected ? Math.cos(midRadian) * 0.1 : 0;
    let offsetY = isSelected ? Math.sin(midRadian) * 0.1 : 0;

    // 计算高亮效果的放大比例（未高亮，则比例为 1）
    let hoverRate = isHovered ? 1.05 : 1;

    // 返回曲面参数方程
    return {
        u: {
            min: -Math.PI,
            max: Math.PI * 3,
            step: Math.PI / 32,
        },

        v: {
            min: 0,
            max: Math.PI * 2,
            step: Math.PI / 20,
        },

        x: function (u, v) {
            if (u < startRadian) {
                return (
                    offsetX +
                    Math.cos(startRadian) * (1 + Math.cos(v) * k) * hoverRate
                );
            }
            if (u > endRadian) {
                return (
                    offsetX +
                    Math.cos(endRadian) * (1 + Math.cos(v) * k) * hoverRate
                );
            }
            return offsetX + Math.cos(u) * (1 + Math.cos(v) * k) * hoverRate;
        },

        y: function (u, v) {
            if (u < startRadian) {
                return (
                    offsetY +
                    Math.sin(startRadian) * (1 + Math.cos(v) * k) * hoverRate
                );
            }
            if (u > endRadian) {
                return (
                    offsetY +
                    Math.sin(endRadian) * (1 + Math.cos(v) * k) * hoverRate
                );
            }
            return offsetY + Math.sin(u) * (1 + Math.cos(v) * k) * hoverRate;
        },

        z: function (u, v) {
            if (u < -Math.PI * 0.5) {
                return Math.sin(u);
            }
            if (u > Math.PI * 2.5) {
                return Math.sin(u);
            }
            return Math.sin(v) > 0 ? 1 * height : -1;
        },
    };
}
export function getPie3D(pieData, internalDiameterRatio) {
    let series = [];
    let sumValue = 0;
    let startValue = 0;
    let endValue = 0;
    let legendData = [];
    let k =
        typeof internalDiameterRatio !== "undefined"
            ? (1 - internalDiameterRatio) / (1 + internalDiameterRatio)
            : 1 / 3;

    // 为每一个饼图数据，生成一个 series-surface 配置
    for (let i = 0; i < pieData.length; i++) {
        sumValue += pieData[i].value;

        let seriesItem = {
            name:
                typeof pieData[i].name === "undefined"
                    ? `series${i}`
                    : pieData[i].name,
            type: "surface",
            parametric: true,
            wireframe: {
                show: false,
            },
            pieData: pieData[i],
            pieStatus: {
                selected: false,
                hovered: false,
                k: k,
            },
        };

        if (typeof pieData[i].itemStyle != "undefined") {
            let itemStyle = {};

            typeof pieData[i].itemStyle.color != "undefined"
                ? (itemStyle.color = pieData[i].itemStyle.color)
                : null;
            typeof pieData[i].itemStyle.opacity != "undefined"
                ? (itemStyle.opacity = pieData[i].itemStyle.opacity)
                : null;

            seriesItem.itemStyle = itemStyle;
        }
        series.push(seriesItem);
    }

    // 使用上一次遍历时，计算出的数据和 sumValue，调用 getParametricEquation 函数，
    // 向每个 series-surface 传入不同的参数方程 series-surface.parametricEquation，也就是实现每一个扇形。
    for (let i = 0; i < series.length; i++) {
        endValue = startValue + series[i].pieData.value;
        series[i].pieData.startRatio = startValue / sumValue;
        series[i].pieData.endRatio = endValue / sumValue;
        series[i].parametricEquation = getParametricEquation(
            series[i].pieData.startRatio,
            series[i].pieData.endRatio,
            false,
            false,
            k,
            series[i].pieData.value
        );

        startValue = endValue;

        legendData.push(series[i].name);
    }
    return series;
}

export function pyramidChart(data = [], dom, option = {}) {
    let domHeight = dom ? dom.clientHeight : 0;
    let domWidth = dom ? dom.clientWidth : 0;
    // 默认获取一个正方形空间
    let maxDistance = domHeight > domWidth / 2 ? domWidth / 2 : domHeight;
    // 合并设置
    let resultOption = Object.assign(
        {
            slanted: 1, // 每层底部的倾斜度
            maxWidth: maxDistance, // 金字塔最大宽度
            maxHeight: maxDistance, // 金字塔最大高度
            offset: 35 //偏差
        },
        option
    );
    if (data.length === 1) {
        resultOption.slanted = 50;
    }
    if (data.length === 2) {
        resultOption.slanted = 25;
    }
    if (data.length === 3) {
        resultOption.slanted = 10;
    }
    if (data.length === 4) {
        resultOption.slanted = 5;
    }
    // 减去多余的误差边距
    resultOption.maxHeight = resultOption.maxHeight - resultOption.offset;
    // 一半最大宽度,用于计算左右边距
    let halfMaxWidth = resultOption.maxWidth / 2;
    // 数据最终
    let resultData = [];
    // 数据值 数组
    let dataNums = data.map(item => item.value || 0);
    // 计算数据总和
    let dataNumSum =
        dataNums.length > 0 &&
        dataNums.reduce(function (prev, curr) {
            return Number(prev || 0) + Number(curr || 0);
        });
    // 中间数据点坐标数组 根据长度比值算出
    let midlinePoint = [];
    let multipleLayer = [0.6];
    // 计算倍数等基础数据
    dataNums.forEach((item, index, arr) => {
        let itemNext = arr[index + 1];
        if (itemNext) {
            multipleLayer.push(itemNext / dataNums[0]); // 计算倍数
        }
        // 计算点坐标 长度
        let point =
            Math.round((item / dataNumSum) * resultOption.maxHeight * 1000) / 1000;
        midlinePoint.push(point);
    });
    // 三角形的高度
    let triangleHeight = 0;
    let triangleHeightLayer = [];
    // 三角形tan角度
    let triangleRatio = halfMaxWidth / resultOption.maxHeight;
    midlinePoint.forEach(item => {
        triangleHeight = triangleHeight + item;
        triangleHeightLayer.push(triangleHeight);
    });
    // 中间数据点 最后的数据长度
    let midlinePointFinally =
        triangleHeightLayer[triangleHeightLayer.length - 1] || 0;
    // 开始拼接数据
    data.forEach((item, index) => {
        let arrObj = [];
        let triangleHeightLayerOne = triangleHeightLayer[index];
        let triangleHeightLayerOneLast = triangleHeightLayer[index - 1] || 0;
        let multipleLayerOne = multipleLayer[index];
        let multipleLayerOneLast = multipleLayer[index - 1] || 0;
        // 第一层数据单独处理
        if (index === 0) {
            arrObj.push(
                [0, 0],
                [
                    -triangleRatio *
                    (triangleHeightLayerOne - resultOption.slanted * multipleLayerOne),
                    triangleHeightLayerOne - resultOption.slanted * multipleLayerOne
                ],
                [0, triangleHeightLayerOne],
                [
                    triangleRatio *
                    (triangleHeightLayerOne - resultOption.slanted * multipleLayerOne),
                    triangleHeightLayerOne - resultOption.slanted * multipleLayerOne
                ]
            );
        } else {
            arrObj.push(
                [0, triangleHeightLayerOneLast],
                [
                    -triangleRatio *
                    (triangleHeightLayerOneLast -
                        resultOption.slanted * multipleLayerOneLast),
                    triangleHeightLayerOneLast -
                    resultOption.slanted * multipleLayerOneLast
                ],
                [
                    -triangleRatio *
                    (triangleHeightLayerOne - resultOption.slanted * multipleLayerOne),
                    triangleHeightLayerOne - resultOption.slanted * multipleLayerOne
                ],
                [0, triangleHeightLayerOne],
                [
                    triangleRatio *
                    (triangleHeightLayerOne - resultOption.slanted * multipleLayerOne),
                    triangleHeightLayerOne - resultOption.slanted * multipleLayerOne
                ],
                [
                    triangleRatio *
                    (triangleHeightLayerOneLast -
                        resultOption.slanted * multipleLayerOneLast),
                    triangleHeightLayerOneLast -
                    resultOption.slanted * multipleLayerOneLast
                ]
            );
        }
        resultData.push({
            type: 'polygon',
            z: 1,
            shape: {
                points: arrObj
            },
            name: item.name,
            style: item.style
        });
    });
    // 添加线
    resultData.push({
        type: 'polyline',
        shape: {
            points: [
                [0, 0],
                [0, midlinePointFinally]
            ]
        },
        style: {
            stroke: '#f2f2f2',
            opacity: 0.2,
            lineWidth: 1
        },
        z: 2
    });
    // 返回
    return resultData;
}
export function getOrderMarkerDom(marker,zoom=18){
    let coefficient=24;
    if(zoom<16){
        coefficient=30;
    }
    if(zoom<15.5){
        coefficient=50;
    }
    if(zoom<15){
        coefficient=70;
    }
    if(zoom<14.5){
        coefficient=100;
    }
    let info=document.createElement('div');
    setObjStyleAttr(info,{width:'100%',textAlign:'center',display:zoom<15.5?'none':'block'});

    let number=document.createElement('span');
    number.innerText=marker.number;
    setObjStyleAttr(number,{fontSize:(48/coefficient*zoom)+'px',color:'#ffea49',marginRight:'10px'})
    info.appendChild(number);

    let unit=document.createElement('span');
    unit.innerText=marker.unit;
    setObjStyleAttr(unit,{color:'#ffea49',fontSize:(22/coefficient*zoom)+'px'})
    info.appendChild(unit);

    let ratio=document.createElement('div');
    setObjStyleAttr(ratio,{width:'100%',display:zoom<15.5?'none':'flex',alignItems:'center',justifyContent:'center'})

    let ratioIcon=document.createElement('img');
    ratioIcon.src=require('@/assets/images/theme-blue/common/'+marker.type+'.png')
    setObjStyleAttr(ratioIcon,{width:(35/coefficient*zoom)+'px',height:(40/coefficient*zoom)+'px',marginRight:'10px'})
    ratio.appendChild(ratioIcon);

    let percentage=document.createElement('div');
    percentage.innerText=marker.percentage+'%';
    setObjStyleAttr(percentage,{color:'#00ec00',fontSize:(28/coefficient*zoom)+'px'})
    ratio.appendChild(percentage);

    let name=document.createElement('div');
    name.innerText=marker.name;
    setObjStyleAttr(name,{width:'100%',display:zoom<15?'none':'flex',justifyContent:'center',color:'#00e0fd',fontSize:(28/coefficient*zoom)+'px',position:'absolute',bottom:'-5px'})

    let dom=document.createElement('div');
    dom.className='map-base-container';
    setObjStyleAttr(dom,{width:(300/coefficient*zoom)+'px',height:(200/coefficient*zoom)+'px',display:'flex',alignItems:'center',justifyContent:'center',backgroundSize:'100% auto',backgroundPosition:'center',backgroundRepeat:'no-repeat'})
    dom.appendChild(info);
    dom.appendChild(ratio);
    dom.appendChild(name);
    return dom
}

export function getMaintenanceMarkerDom(marker){
    let dom=document.createElement('div');
    dom.className='map-warning '+(marker.type==1?'warning':'danger');

    let name=document.createElement('div');
    name.className='warning-name';
    name.innerText=marker.name;

    let type=document.createElement('div');
    type.className='warning-text';
    type.innerText=marker.type==1?'设备离线告警':'设备异常告警';

    dom.appendChild(name);
    dom.appendChild(type);
    return dom;
}

function setObjStyleAttr(obj,attr){
    Object.keys(attr).forEach((item)=>{
        obj.style[item]=attr[item];
    })
}

export function getHeatMap(data){
    let result=[]
    data.forEach(item => {
        for (let i = 0; i < 3; i++) {
            const index1 = getRandomData(1, 0, 1)[0] == 1 ? item.coord[0] + getRandomData(1000, 0, 1)[0] / 100000 : item.coord[0] - getRandomData(1000, 0, 1)[0] / 100000;
            const index2 = getRandomData(1, 0, 1)[0] == 1 ? item.coord[1] + getRandomData(1000, 0, 1)[0] / 100000 : item.coord[1] - getRandomData(1000, 0, 1)[0] / 100000
            const coord = [index1, index2];
            result.push({value: getRandomData(100000000, 0, 1)[0] * 1, coord,})
        }
    })
    return result;
}
